package com.gzs.learn.admin.common.utils.ip;

import com.gzs.learn.admin.common.config.AdminConfig;
import com.gzs.learn.admin.common.utils.StringUtils;
import com.gzs.learn.common.util.HttpUtil;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanMap;

import java.util.Map;

/**
 * 地址转换类，使用高德开放API平台提供接口
 *
 * @author guanzhisong
 */
@Slf4j
public class AddressUtils {
    public static final String IP_URL = "https://restapi.amap.com/v3/ip";
    public static final String UNKNOW_IP = "unknow";

    public static String getRealAddressByIp(String ip) {
        String address = UNKNOW_IP;
        // 内网不查询
        if (IpUtils.internalIp(ip)) {
            return "内网IP";
        }
        if (!AdminConfig.isAddressEnabled()) {
            return address;
        }
        @SuppressWarnings("unchecked")
        Map<String, Object> paramMap = BeanMap.create(IpRequest.builder().key(AdminConfig.getAmapKey()).ip(ip).build());
        String url = HttpUtil.buildUrl(IP_URL, HttpUtil.convertMap2Pair(paramMap));
        try {
            HttpUtil.Response<IpResult> resp = HttpUtil.doGet(url, IpResult.class);
            if (resp.isSuccess() && resp.getEntity() != null && resp.getEntity().isSuccess()) {
                IpResult result = resp.getEntity();
                if (result != null) {
                    address = result.getProvince() + "," + result.getCity();
                }
            }
        } catch (Exception e) {
            log.error("get ip {} addr error ", ip, e);
        }
        return address;
    }

    public static boolean isUnknow(String address) {
        return StringUtils.equalsIgnoreCase(address, UNKNOW_IP);
    }
}

@Data
@Builder()
class IpRequest {
    private String key;
    private String ip;
    @Builder.Default()
    private String output = "JSON";
}

@Data
class IpResult {
    private static final String INFOCODE_SUCCESS = "10000";
    private String status;
    private String info;
    private String infocode;
    private String province;
    private String city;
    private String adcode;
    private String rectangle;

    public boolean isSuccess() {
        return StringUtils.equalsIgnoreCase(getInfocode(), INFOCODE_SUCCESS) && StringUtils.equalsIgnoreCase(status, "1");
    }
}
